package sdk.webview.fmc.com.fmcsdk.util;

import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.preference.PreferenceManager;
import android.provider.MediaStore;
import android.support.v4.content.FileProvider;
import android.text.TextUtils;
import android.util.Base64;
import android.util.Log;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.text.DecimalFormat;

import okhttp3.MediaType;
import okhttp3.RequestBody;
import sdk.webview.fmc.com.fmcsdk.base.UserApi;
import sdk.webview.fmc.com.fmcsdk.bean.UploadImage;
import sdk.webview.fmc.com.fmcsdk.interfaces.OnDialogStringListener;
import sdk.webview.fmc.com.fmcsdk.interfaces.OnDialogSureListener;
import sdk.webview.fmc.com.fmcsdk.util.retrofit2.observer.ResponseTransformer;
import sdk.webview.fmc.com.fmcsdk.util.retrofit2.subscriber.ResponseSubscriber;
import top.zibin.luban.OnCompressListener;

public class FileUtil {


    /**
     * <p>将文件转成base64 字符串</p>
     *
     * @param path 文件路径
     * @return
     * @throws Exception
     */
    public static String encodeBase64File(String path) throws Exception {
        File file = new File(path);
        FileInputStream inputFile = new FileInputStream(file);
        byte[] buffer = new byte[(int) file.length()];
        inputFile.read(buffer);
        inputFile.close();
        return Base64.encodeToString(buffer, Base64.NO_WRAP);
    }

    /**
     * 转换文件大小
     *
     * @param fileS
     */
    public static String formatFileSize(long fileS) {
        DecimalFormat df = new DecimalFormat("#.00");
        String fileSizeString = "";
        String wrongSize = "0B";
        if (fileS == 0) {
            return wrongSize;
        }
        if (fileS < 1024) {
            fileSizeString = df.format((double) fileS) + "B";
        } else if (fileS < 1048576) {
            fileSizeString = df.format((double) fileS / 1024) + "KB";
        } else if (fileS < 1073741824) {
            fileSizeString = df.format((double) fileS / 1048576) + "MB";
        } else {
            fileSizeString = df.format((double) fileS / 1073741824) + "GB";
        }
        return fileSizeString;
    }

    /**
     * <p>将文件转成base64 字符串并压缩到30K以下返回缩略图</p>
     *
     * @param path 文件路径
     * @return
     * @throws Exception
     */
    public static String encodeBase64FileToThum(String path, Context context) throws Exception {
        Bitmap temp = getBitmap(ImageUtils.getH5ImagePath(path, context));
        ByteArrayOutputStream baos = new ByteArrayOutputStream();

        int quality = 100;
        temp.compress(Bitmap.CompressFormat.JPEG, quality, baos);
        while (baos.toByteArray().length > 60 * 1024) {
            baos.reset();
            temp.compress(Bitmap.CompressFormat.JPEG, quality, baos);
            quality -= 5;
            if (quality < 0) {
                break;
            }
        }

        if (temp != null && !temp.isRecycled()) {
            temp.recycle();
        }

        try {
            baos.writeTo(new FileOutputStream(ImageUtils.getH5ImageThumPath(path, context)));
            baos.flush();
            baos.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

        File file = new File(ImageUtils.getH5ImageThumPath(path, context));
        FileInputStream inputFile = new FileInputStream(file);
        byte[] buffer = new byte[(int) file.length()];
        inputFile.read(buffer);
        inputFile.close();
        return Base64.encodeToString(buffer, Base64.NO_WRAP);
    }


    /**
     * <p>将文件转成base64 字符串并先根据宽100压缩然后压缩到百分之50</p>
     *
     * @param path 文件路径
     * @return
     * @throws Exception
     */
    public static String encodeBase64FileToThumToH5(String path, Context context) throws Exception {
        return encodeBase64Toh5(path, context);
    }
    public static void encodeBase64FileToThumToH5Listener(String path, Context context, OnDialogStringListener onDialogStringListener) throws Exception {
        new ImageCompressor(context).compressImageInPlace(ImageUtils.getH5ImagePath(path, context), new OnCompressListener() {
            @Override
            public void onStart() {
            }
            @Override
            public void onSuccess(File file) {
                try {
                    String urlBase=fileToBase64(file);
                    onDialogStringListener.onDialogSureListener(urlBase);
                } catch (Exception e) {
                    e.printStackTrace();
                    try {
                        onDialogStringListener.onDialogSureListener(encodeBase64Toh5(path, context));
                    } catch (Exception ex) {
                        ex.printStackTrace();
                    }
                }
            }

            @Override
            public void onError(Throwable e) {

            }
        });
    }


    public static String encodeBase64Toh5(String path, Context context) throws Exception {
        Bitmap temp = getBitmap(ImageUtils.getH5ImagePath(path, context));
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        temp.compress(Bitmap.CompressFormat.JPEG, 80, baos);
        if (temp != null && !temp.isRecycled()) {
            temp.recycle();
        }
        try {
            baos.writeTo(new FileOutputStream(ImageUtils.getH5ImageThumPath(path, context)));
            baos.flush();
            baos.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

        File file = new File(ImageUtils.getH5ImageThumPath(path, context));
        FileInputStream inputFile = new FileInputStream(file);
        byte[] buffer = new byte[(int) file.length()];
        inputFile.read(buffer);
        inputFile.close();
        return Base64.encodeToString(buffer, Base64.NO_WRAP);
    }


    public static String encodeBase64Toh5Url(String path, Context context) throws Exception {
        Bitmap temp = getBitmap(path);
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        temp.compress(Bitmap.CompressFormat.JPEG, 80, baos);
        if (temp != null && !temp.isRecycled()) {
            temp.recycle();
        }
        try {
            baos.writeTo(new FileOutputStream(ImageUtils.getH5ImageThumPath(path, context)));
            baos.flush();
            baos.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

        File file = new File(ImageUtils.getH5ImageThumPath(path, context));
        FileInputStream inputFile = new FileInputStream(file);
        byte[] buffer = new byte[(int) file.length()];
        inputFile.read(buffer);
        inputFile.close();
        return Base64.encodeToString(buffer, Base64.NO_WRAP);
    }

    public static Bitmap compressImageToWidth(String imagePath, int targetWidth) {
        BitmapFactory.Options bounds = new BitmapFactory.Options();
        bounds.inJustDecodeBounds = true;
        BitmapFactory.decodeFile(imagePath, bounds);
        int ratio = bounds.outHeight / bounds.outWidth;

        // Find the ratio of the width and target width
        int widthRatio = Math.round((float) bounds.outWidth / (float) targetWidth);
        int heightRatio = Math.round((float) bounds.outHeight / (float) targetWidth);

        // Use the largest ratio to reduce the image size
        BitmapFactory.Options opts = new BitmapFactory.Options();
        opts.inSampleSize = widthRatio > heightRatio ? widthRatio : heightRatio;

        // Decode the image with inSampleSize set
        Bitmap img = BitmapFactory.decodeFile(imagePath, opts);

        return img;
    }

    /**
     * 根据宽度进行等比压缩
     *
     * @param imagePath
     * @param targetWidth
     * @return
     */
    public static Bitmap compressImageWidth(String imagePath, int targetWidth) {
        BitmapFactory.Options bounds = new BitmapFactory.Options();
        bounds.inJustDecodeBounds = true;
        BitmapFactory.decodeFile(imagePath, bounds);
        int ratio = bounds.outHeight / bounds.outWidth;

        BitmapFactory.Options opts = new BitmapFactory.Options();
        opts.inSampleSize = bounds.outWidth / targetWidth;

        Bitmap bitmap = BitmapFactory.decodeFile(imagePath, opts);
        int targetHeight = bitmap.getHeight() / opts.inSampleSize;

        // Resize the bitmap if width is more than targetWidth
        if (targetWidth < bitmap.getWidth()) {
            bitmap = Bitmap.createScaledBitmap(bitmap, targetWidth, targetHeight, true);
        }

        return bitmap;
    }

    private static Bitmap getBitmap(String pathString) {
        Log.e("shuchang", "给h5的url--bp->" + pathString);
        try {
            File file = new File(pathString);
            if (file.exists()) {
                return BitmapFactory.decodeFile(pathString);
            }
        } catch (Exception e) {

        }
        return null;
    }

    /**
     * 获取大小
     *
     * @param path
     * @return
     * @throws Exception
     */
    public static long getFileSize(String path) {
        File file = new File(path);
        return file.length();
    }


    /**
     * 删除文件夹及其子文件
     *
     * @param file
     */
    public static void deleteFile(final File file) {
        try {
            //是文件直接删除
            if (file.isFile()) {
                file.delete();
                return;
            }
            if (file.isDirectory()) {
                File[] childFiles = file.listFiles();
                //是空目录直接删除
                if (childFiles == null || childFiles.length == 0) {
                    file.delete();
                    return;
                }
                //有子文件，递归删除
                for (int i = 0; i < childFiles.length; i++) {
                    deleteFile(childFiles[i]);
                }
                file.delete();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 删除某APK文件夹下面的apk
     */
    public static void deleteApkFile(final String path) {
        File file = new File(path);
        if (file.exists()) {
            if (file.isDirectory()) {
                File[] files = file.listFiles();
                if (files != null) {
                    for (int i = 0; i < files.length; i++) {
                        File f = files[i];
                        deleteFile(f);
                    }
                }
            }
        }
    }

    /**
     * 删除localStorage缓存
     *
     * @param context
     */
    public static void deleteLocalStorageFile(Context context) {
        final String path = "/data/data/" + context.getPackageName() + "/app_webview/Local Storage";
        File file = new File(path);
        if (file.exists()) {
            if (file.isDirectory()) {
                File[] files = file.listFiles();
                for (int i = 0; i < files.length; i++) {
                    File f = files[i];
                    deleteFile(f);
                }
            }
        }

//        final String path2 = "/data/data/" + context.getPackageName()+"cache";
//        File file2 = new File(path2);
//        if (file2.exists()){
//            if (file2.isDirectory()) {
//                File[] files2 = file2.listFiles();
//                for (int i = 0; i < files2.length; i++) {
//                    File f2 = files2[i];
//                    deleteFile(f2);
//                }
//            }
//        }
//        deleteH5URLFile(context);
    }


    /**
     * 删除某一个文件
     */
    public static void deleteOneFile(String path) {
        File file = new File(path);
        if (file.exists()) {
            file.delete();//删除文件
        }
    }

//    //保存数据到本地文件
//    public static String saveH5DataToLocal(String dataName,String dataValue) {
//        BufferedWriter writer = null;
//        File file = new File(Constant.JSONPATH+"/"+UserHelper.getUserName());
//        if (!file.exists()){
//            file.mkdirs();
//        }
//        File fileName = new File(Constant.JSONPATH+"/"+UserHelper.getUserName()+"/"+dataName + ".json");
//        //如果文件存在，先删除在写入
//        if (fileName.exists()) {
//
//            boolean delete = fileName.delete();
//            XLog.i("删除"+fileName+"--"+delete);
//        }
//        try {
//            fileName.createNewFile();
//        } catch (IOException e) {
//            e.printStackTrace();
//            return dataName+"--"+e.toString();
//        }
//
//        //写入
//        try {
//            writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(fileName,false), "UTF-8"));
//            writer.write(dataValue);
//        } catch (IOException e) {
//            e.printStackTrace();
//            return dataName+"--"+e.toString();
//        }finally {
//            try {
//                if(writer != null){
//                    writer.close();
//                }
//            } catch (IOException e) {
//                e.printStackTrace();
//                return dataName+"--"+e.toString();
//            }
//        }
//        return "保存数据:"+dataName+"--到本地成功";
//    }

//    //获取本地数据文件
//    public static String getH5DataForLocal(String dataName) {
//        File fileName = new File(Constant.JSONPATH+"/"+UserHelper.getUserName()+"/"+dataName + ".json");
//        //如果文件不存在
//        if(!fileName.exists()){
//            return "";
//        }
//
//        BufferedReader reader = null;
//        String laststr = "";
//        try {
//            FileInputStream fileInputStream = new FileInputStream(fileName);
//            InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream, "UTF-8");
//            reader = new BufferedReader(inputStreamReader);
//            String tempString = null;
//            while ((tempString = reader.readLine()) != null) {
//                laststr += tempString;
//            }
//            reader.close();
//        } catch (IOException e) {
//            e.printStackTrace();
//            return dataName+"--"+e.toString();
//        } finally {
//            if (reader != null) {
//                try {
//                    reader.close();
//                } catch (IOException e) {
//                    e.printStackTrace();
//                    return dataName+"--"+e.toString();
//                }
//            }
//        }
//        return laststr;
//    }

//    /**
//     * 删除本地文件
//     * @param dataName 文件名
//     */
//    public static void deleteH5DataForLocal(String dataName) {
//        File fileName = new File(Constant.JSONPATH+"/"+UserHelper.getUserName()+"/"+dataName + ".json");
//        if (fileName.exists()){
//            fileName.delete();
//        }
//    }

    //删除超过3天的日志信息
    public static void deleteLogFiles(Context activity) {
        String storePath;
        if (SdkVersionUtils.checkedAndroid_R()) {
            storePath = activity.getExternalFilesDir(Environment.DIRECTORY_PICTURES).getAbsolutePath() + "/fmc/" + PreferenceManager.getDefaultSharedPreferences(activity).getString(Constant.APP_NAME, "fmsdk");
        } else {
            storePath = activity.getFilesDir().getAbsolutePath() + "/fmc/" + PreferenceManager.getDefaultSharedPreferences(activity).getString(Constant.APP_NAME, "fmsdk");

        }
//        String storePath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/fmc/" + PreferenceManager.getDefaultSharedPreferences(context).getString(Constant.APP_NAME, "fmsdk");
        File file = new File(storePath + Constant.LOGPATH);
        File[] filelist = file.listFiles();
        if (filelist == null) {
            return;
        }
        if (filelist.length >= 0) {
            for (int i = 0; i < filelist.length; i++) {
                long newtime = System.currentTimeMillis();
                String fileName = filelist[i].getName();//遍历的文件时间
                long stamptime = DateUtil.dateToStamptime(fileName.substring(0, 10));

                long time = newtime - stamptime;
                if ((time / (1000 * 60 * 60 * 24)) > 3) {
                    boolean b = filelist[i].delete();
                    if (b) {
                        XLog.i(filelist[i].getName() + "删除成功");
                    }
                }
            }
        }
    }

    public static String getLocalImageUri(Context context, String imageUrl) {
        File imageFile = new File(imageUrl);
        Uri uri;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            uri = FileProvider.getUriForFile(context, context.getPackageName() + ".fileprovider", imageFile);
        } else {
            uri = Uri.fromFile(imageFile);
        }


//        File tempFile = new File(context.getExternalFilesDir(Environment.DIRECTORY_PICTURES), imageUrl);
//        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
//            uri = FileProvider.getUriForFile(context, context.getPackageName() + ".fileprovider", tempFile);
//        } else {
//            uri = Uri.fromFile(tempFile);
//        }

        return uri.toString();
    }


    public static String fileToBase64(File file) {
        String base64 = null;
        InputStream in = null;
        try {
            in = new FileInputStream(file);
            byte[] bytes = new byte[in.available()];
            int length = in.read(bytes);
            base64 = Base64.encodeToString(bytes, 0, length, Base64.NO_WRAP);
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } finally {
            try {
                if (in != null) {
                    in.close();
                }
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        return base64;
    }



    /**
     * 将图片转换成Base64编码的字符串
     */
    public static String imageToBase64(String path){
        if(TextUtils.isEmpty(path)){
            return null;
        }
        InputStream is = null;
        byte[] data = null;
        String result = null;
        try{
            is = new FileInputStream(path);
            //创建一个字符流大小的数组。
            data = new byte[is.available()];
            //写入数组
            is.read(data);
            //用默认的编码格式进行编码
            result = Base64.encodeToString(data,Base64.NO_WRAP);
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            if(null !=is){
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

        }
        return result;
    }

}
